package com.sc.admin.core.bo;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sc.admin.core.dao.SysCompanyMapper;
import com.sc.admin.core.dao.SysMyNoticeMapper;
import com.sc.admin.core.dao.SysNotificationMapper;
import com.sc.admin.core.dao.SysUserOrganizationMapper;
import com.sc.common.context.DefaultBusinessContext;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.company.SysCompany;
import com.sc.common.entity.admin.mynotice.SysMyNotice;
import com.sc.common.entity.admin.notification.SysNotification;
import com.sc.common.entity.admin.userorganization.SysUserOrganization;
import com.sc.common.util.MyIdUtil;
import com.sc.mq.producer.Producer4routingKey;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 系统通知业务对象
 */
@Component
public class NotificationBo {

    @Autowired
    private SysCompanyMapper sysCompanyMapper;

    @Autowired
    private SysUserOrganizationMapper sysUserOrganizationMapper;

    @Autowired
    private SysMyNoticeMapper sysMyNoticeMapper;

    @Autowired
    private SysNotificationMapper sysNotificationMapper;

    @Autowired
    private Producer4routingKey producer4routingKey;

    @Value("${spring.rabbitmq.publishnotification.exchange.name}")
    private String publishnotificationExchange;

    @Value("${spring.rabbitmq.publishnotification.routing-key}")
    private String publishnotificationRoutingKey;

    /**
     * 发布消息，此方法一定要在有事务的方法调用
     * @param id
     * @return
     */
    public WebResponseDto publish(Long id){
        WebResponseDto responseDto = new WebResponseDto();
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();
        SysNotification entity = sysNotificationMapper.selectByPrimaryKey(id);
        if(entity != null) {
            entity.setStatus("A101302");
            entity.setModifyId(ctx.getAccountId());
            entity.setModifyName(ctx.getAccountName());
            entity.setModifyTime(new Date());
            sysNotificationMapper.updateByPrimaryKey(entity);


            Set<Long> keys = new HashSet<>(100);
            String receiverType = entity.getReceiverType();
            String receiverString = entity.getReceiver();
            if("A101401".equals(receiverType)) { // 当前系统所有用户
                SysUserOrganization sysUserOrganizationSearch = new SysUserOrganization();
                List<SysUserOrganization> userOrganizations = sysUserOrganizationMapper.select(sysUserOrganizationSearch);
                List<SysMyNotice> myNotices = new ArrayList<>(userOrganizations.size());
                for (SysUserOrganization userOrganization : userOrganizations) {
                    if(keys.contains(userOrganization.getUserId())){
                        continue;
                    }
                    keys.add(userOrganization.getUserId());

                    SysMyNotice sysMyNotice = new SysMyNotice();
                    sysMyNotice.setId(MyIdUtil.getId());
                    sysMyNotice.setNotificationId(id);
                    sysMyNotice.setReceiver(userOrganization.getUserId());
                    sysMyNotice.setStatus("A101502");
                    sysMyNotice.setCreaterId(ctx.getAccountId());
                    sysMyNotice.setCreaterName(ctx.getAccountName());
                    sysMyNotice.setCreateTime(new Date());
                    myNotices.add(sysMyNotice);
                }
                if(CollectionUtils.isNotEmpty(myNotices)){
                    sysMyNoticeMapper.insertList(myNotices);
                }
            }else if("A101402".equals(receiverType)) { // 公司用户
                SysUserOrganization sysUserOrganizationSearch = new SysUserOrganization();
                sysUserOrganizationSearch.setBranchCompanyId(Long.valueOf(receiverString));
                List<SysUserOrganization> userOrganizations = sysUserOrganizationMapper.select(sysUserOrganizationSearch);
                List<SysMyNotice> myNotices = new ArrayList<>(userOrganizations.size());
                for (SysUserOrganization userOrganization : userOrganizations) {
                    if(keys.contains(userOrganization.getUserId())){
                        continue;
                    }
                    keys.add(userOrganization.getUserId());

                    SysMyNotice sysMyNotice = new SysMyNotice();
                    sysMyNotice.setId(MyIdUtil.getId());
                    sysMyNotice.setNotificationId(id);
                    sysMyNotice.setReceiver(userOrganization.getUserId());
                    sysMyNotice.setStatus("A101502");
                    sysMyNotice.setCreaterId(ctx.getAccountId());
                    sysMyNotice.setCreaterName(ctx.getAccountName());
                    sysMyNotice.setCreateTime(new Date());
                    myNotices.add(sysMyNotice);
                }
                if(CollectionUtils.isNotEmpty(myNotices)){
                    sysMyNoticeMapper.insertList(myNotices);
                }
            }else if("A101403".equals(receiverType)) { // 项目用户
                SysUserOrganization sysUserOrganizationSearch = new SysUserOrganization();
                sysUserOrganizationSearch.setProjectId(Long.valueOf(receiverString));
                List<SysUserOrganization> userOrganizations = sysUserOrganizationMapper.select(sysUserOrganizationSearch);
                List<SysMyNotice> myNotices = new ArrayList<>(userOrganizations.size());
                for (SysUserOrganization userOrganization : userOrganizations) {
                    if(keys.contains(userOrganization.getUserId())){
                        continue;
                    }
                    keys.add(userOrganization.getUserId());

                    SysMyNotice sysMyNotice = new SysMyNotice();
                    sysMyNotice.setId(MyIdUtil.getId());
                    sysMyNotice.setNotificationId(id);
                    sysMyNotice.setReceiver(userOrganization.getUserId());
                    sysMyNotice.setStatus("A101502");
                    sysMyNotice.setCreaterId(ctx.getAccountId());
                    sysMyNotice.setCreaterName(ctx.getAccountName());
                    sysMyNotice.setCreateTime(new Date());
                    myNotices.add(sysMyNotice);
                }

                if(CollectionUtils.isNotEmpty(myNotices)){
                    sysMyNoticeMapper.insertList(myNotices);
                }
            }

            pushToMyNoticeQueue(entity,"1");
        }else {
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("发布失败，该记录已经不存在");
        }
        return responseDto;
    }

    /**
     * 发送消息到我的通知队列
     * @param notification
     * @param opt 1表示有新消息发布，2表示需要监听者重新读取我的未读消息数量
     */
    public void pushToMyNoticeQueue(SysNotification notification, String opt){
        JSONObject jsonObject = new JSONObject();
        if("1".equals(opt)){
            jsonObject.put("receiverType",notification.getReceiverType());
            jsonObject.put("receiver",notification.getReceiver());
            jsonObject.put("notificationId",notification.getId());
            jsonObject.put("priorityLevel",notification.getPriorityLevel());
            jsonObject.put("title",notification.getTitle());
            jsonObject.put("sendChannel",notification.getSendChannel());
        }
        jsonObject.put("opt",opt);
        jsonObject.put("ctx",DefaultBusinessContext.getContext());

        String exchangeName = publishnotificationExchange;
        String routingKey = publishnotificationRoutingKey;
        producer4routingKey.send(exchangeName,routingKey,jsonObject);
    }

    public JSONArray buildReceiverCascaderByReceiverType(String receiverType){
        final JSONArray jsonArray = new JSONArray();

        if("A101402".equals(receiverType)) { // 公司用户
            /**
             * 分公司列表
             */
            SysCompany companySearch = new SysCompany();
            companySearch.setType("A101107");
            List<SysCompany> companyList =  sysCompanyMapper.select(companySearch);
            if(CollectionUtil.isNotEmpty(companyList)){
                for (SysCompany company : companyList) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("value",company.getId());
                    jsonObject.put("label",company.getName());
                    jsonObject.put("children",null);
                    jsonArray.add(jsonObject);
                }
            }
        }else if("A101403".equals(receiverType)) { // 项目用户
            /**
             * 分公司列表
             */
            SysCompany companySearch = new SysCompany();
            companySearch.setType("A101107");
            List<SysCompany> companyList =  sysCompanyMapper.select(companySearch);
            if(CollectionUtil.isNotEmpty(companyList)){
                for (SysCompany company : companyList) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("value",company.getId());
                    jsonObject.put("label",company.getName());


                    /**
                     * 项目列表
                     */
                    List<Map> projectMapList = sysUserOrganizationMapper.findProjectByBranchCompanyId(company.getId());
                    if(CollectionUtil.isNotEmpty(projectMapList)){
                        JSONArray projectJsonArray = new JSONArray();
                        for (Map map : projectMapList) {
                            if(CollectionUtil.isEmpty(map)){
                                continue;
                            }
                            JSONObject projectJsonObject = new JSONObject();
                            projectJsonObject.put("value",map.get("id"));
                            projectJsonObject.put("label",map.get("name"));
                            projectJsonArray.add(projectJsonObject);
                        }
                        jsonObject.put("children",projectJsonArray);
                    }

                    jsonArray.add(jsonObject);
                }
            }
        }
        return jsonArray;
    }
}
